package com.zenith.yasoo.security;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.Cookie;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.zui.base.BaseAction;
import com.zui.base.EntityManager;
import com.zui.base.ZuiConstants;

public class UserAction extends BaseAction {

	private static final long serialVersionUID = 1L;

	public UserAction(UserManager userManager) {
		this.userManager = userManager;
	}

	private User user;
	private EntityManager roleManager;
	private List userList = new ArrayList();
	private List roleList = new ArrayList();
	private List selectRoleList = new ArrayList();
	private UserManager userManager;
	private EntityManager serveParameterManaegr;
	private Md5PasswordEncoder md5PasswordEncoder;

	private JavaMailSenderImpl mailSender;
	/** 找回密码邮件模版 */
	private SimpleMailMessage retrievePasswordMessage;

	/**
	 * 找回密码的Action
	 */
	public static final String RETRIEVE_PASSWORD_ACTION = "/doRetrievePassword.do";

	/**
	 * 找回密码链接地址的参数
	 */
	public static final String PARAM_ACCOUNT_NAME = "user._email";

	/**
	 * 找回密码链接地址的参数
	 */
	public static final String PARAM_MESSAGE = "user.oldPassword";

	public String showLoginPage() {
		if (getCurrentUser() != null)
			return "homePage";

		log.debug("showLoginPage() method in class UserAction is executed!");
		configUserLocale();
		return "loginPage";
	}

	public String showHomePage() {
		return "homePage";
	}

	/**
	 * 假如还没有登录，需要选用用户在本地设置的语言，如果未设置过则选用操作系统 的默认语言; 假如已经登录，则选用用户设置的语言；
	 */
	private void configUserLocale() {
		User user = getCurrentUser();
		String request_locale = null;
		String localeInCookie = getLocaleFromCookie();
		if (user != null) {
			if (user.getLastLocale() != null) // use last_locale firstly.
				request_locale = user.getLastLocale();
			else if (localeInCookie != null && !"".equals(localeInCookie))
				request_locale = localeInCookie;// else get cookie locale
												// secondly.
			// else use the system default.
		} else if (localeInCookie != null && !"".equals(localeInCookie))
			request_locale = localeInCookie;
		
		log.debug("The default request locale from client is [" + request.getLocale() + "]");

		setLocaleInSessionCookie(request_locale);
	}

	private String getLocaleFromCookie() {
		Cookie[] cookies = this.getRequest().getCookies();
		String request_locale = null;
		for (Cookie cookie : cookies)
			if (ZuiConstants.LOCALE_COOKIE_NAME.equals(cookie.getName())) {
				request_locale = cookie.getValue();
				break;
			}
		return request_locale;
	}

	/**
	 * set locale to session, current action and cookie
	 * 
	 * @param locale
	 *            the string representation like "en_US_WIN"
	 */
	private void setLocaleInSessionCookie(String request_locale) {

		if (request_locale == null || "".equals(request_locale))
			request_locale = ZuiConstants.LOCALE_APPLICATION_DEFAULT;

		Locale locale = LocalizedTextUtil
				.localeFromString(request_locale, null);

		// sets local in session for action i18ninterceptor
		request.getSession().setAttribute(ZuiConstants.WW_TRANS_I18N_LOCALE,
				locale);

		// Sets the Locale for the current action
		ActionContext.getContext().setLocale(locale);

		// Sets the Locale for client cookie
		Cookie cookie = new Cookie(ZuiConstants.LOCALE_COOKIE_NAME, locale
				.toString());
		cookie.setMaxAge(365 * 24 * 60 * 60);
		response.addCookie(cookie);
		
		log.debug("The request locale [" + request_locale + "] was stored in cookie and current session.");
	}

	/**
	 * 保存账户
	 * 
	 * @return
	 */
	public String saveUser() {
		// if(user == null)
		// return INPUT;
		// if(user.getUserName() == null ||
		// user.getUserName().trim().equals("")){
		// addActionError("User name is required!");
		// return INPUT;
		// }
		// if(user == null || user.getId() == null){
		// if(user.getPassword() == null ||
		// user.getPassword().trim().equals("")){
		// addActionError("Password is required!");
		// return INPUT;
		// }
		// if(user.getConfirmPassword() == null ||
		// user.getConfirmPassword().trim().equals("")){
		// addActionError("Confirm password is required!");
		// return INPUT;
		// }
		// if(!user.getPassword().trim().equals(user.getConfirmPassword().trim())){
		// addActionError("Password and confirm password is not the same!");
		// return INPUT;
		// }
		// }
		// Set<Role> roleSet = new LinkedHashSet<Role>();
		// // if(user.getRolesInSelect() == null ||
		// user.getRolesInSelect().equals("")){
		// // addActionError("role is required!");
		// // return INPUT;
		// // }
		// // else{
		// // String[] str = user.getRolesInSelect().split(",");
		// // for(int i=0 ;i<str.length; i++){
		// // roleSet.add(new Role(str[i].trim()));
		// // }
		// }
		// // if(user.getEmail() == null || "".equals(user.getEmail().trim())){
		// // addActionError("Email is required!");
		// // return INPUT;
		// // }
		//			
		//		
		// user.setRoles(roleSet);
		// if(user.getId() != null)
		// userManager.updateEntity(user);
		// else{
		// user.setPassword(md5PasswordEncoder.encodePassword(user.getPassword(),
		// null));
		// userManager.saveEntity(user);
		// }
		return SUCCESS;
	}

	/**
	 * 修改账户
	 * 
	 * @return
	 */
	public String updateUser() {
		if (user == null || user.getId() == null)
			return INPUT;
		user = (User) userManager.findById(user.getId());
		if (user.getRoles() != null) {
			for (Iterator<Role> it = user.getRoles().iterator(); it.hasNext();) {
				selectRoleList.add(it.next());
			}
		}

		return SUCCESS;
	}

	/**
	 * 查询账户
	 * 
	 * @return
	 */
	public String listUser() {
		try {
			DetachedCriteria criteria = getCriteria(user);
			// userList = userManager.divPage(criteria, page==null?new
			// Page():page);
		} catch (RuntimeException e) {
			e.printStackTrace();
			return SUCCESS;
		}
		return SUCCESS;
	}

	public static DetachedCriteria getCriteria(User user) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("isDelete",
				com.zenith.yasoo.security.User.IS_DELETED_N));
		if (user != null) {
			if (user.getUserName() != null
					&& !"".equals(user.getUserName().trim())) {
				criteria.add(Restrictions.like("userName", user.getUserName(),
						MatchMode.ANYWHERE));
			}
		}
		return criteria;
	}

	/**
	 * 删除
	 * 
	 * @return
	 */
	public String deleteUser() {
		if (user == null || user.getId() == null)
			return INPUT;
		user = (User) userManager.findById(user.getId());
		user.setIsDeleted(com.zenith.yasoo.security.User.IS_DELETED_N);
		userManager.merge(user);
		return SUCCESS;
	}

	/**
	 * 登陆成功后首先执行此方法。
	 * 
	 * @return
	 */
	public String afterAcegi() {

		// save user in session
		User user = null;
		String remoteUserName = null;
		Object principal = SecurityContextHolder.getContext()
				.getAuthentication().getPrincipal();
		if (principal instanceof User)
			user = ((User) principal);
		else {
			if (principal instanceof UserDetails)
				remoteUserName = ((UserDetails) principal).getUsername();
			else
				remoteUserName = principal.toString();

			if (remoteUserName != null)
				user = (User) userManager.getUserByLoginName(remoteUserName);
			else
				return SUCCESS;
		}

		if (user != null) {
			request.getSession().setAttribute(
					ZuiConstants.USER_INFO_IN_SESSION, user);
			log.debug("User with username [" + user.getUserName()
					+ "] has logined successfully!");
		} else
			log.debug("Username [" + remoteUserName + "] was not find!");
		
		//config user locale
		configUserLocale();

		return SUCCESS;
	}

	/**
	 * 修改密码
	 */
	public void ajaxUpdate() {
		// boolean bool = false;
		// String msg = "Err！";
		// if(user == null){
		// bool = true;
		// msg = "Parameters lost";
		// }
		// user.setOldPassword(md5PasswordEncoder.encodePassword(user.getOldPassword(),
		// null));
		// user.setPassword(md5PasswordEncoder.encodePassword(user.getPassword(),
		// null));
		// int num = userManager.updateByNamedQuery("User.updatePassword", new
		// Object[]{user.getPassword(),user.getUserName(),user.getOldPassword()});
		// if(num>0){
		// msg = "Change your password success!";
		// bool = true;
		// }else
		// msg = "The original password error！";
		// StringBuffer sb = new StringBuffer();
		// sb.append("<?xml version=\"1.0\" ?>");
		// sb.append("<message>");
		// sb.append("<operation>" + bool + "</operation>");
		// sb.append("<msg>" + msg + "</msg>");
		// sb.append("</message>");
		//
		// sampleAjax(sb.toString());
	}

	/**
	 * 发送找回密码的邮件
	 * 
	 * @return
	 */
	public String forgetPassword() {
		if (user == null)
			return INPUT;
		if (user.getUserName() == null || "".equals(user.getUserName().trim())) {
			addActionError("UserName is required");
			return INPUT;
		}
		// if(user.getEmail() == null || "".equals(user.getEmail().trim())){
		// addActionError("Email is required");
		// return INPUT;
		// }
		//		
		// List<User> list =
		// userManager.findByNamedQuery("User.findByUserAndPass", new
		// Object[]{user.getUserName(),user.getEmail()});
		// if(list == null || list.size()<1){
		// addActionError("UserName and Email do not meet");
		// return INPUT;
		// }
		// user = list.get(0);
		// //设置找回密码的链接:系统地址+找回密码.do+Email参数+password参数
		// List<ServeParameter> spList =
		// serveParameterManaegr.findByCriteria(ServeParameterAction.getCriteria());
		// if(spList == null || spList.size() ==0){
		// addActionError("Please config your Email!");
		// return INPUT;
		// }
		// ServeParameter sp = spList.get(0);
		// retrievePasswordMessage.setFrom(sp.getEmailAddress());
		// mailSender.setHost(sp.getHost());
		// mailSender.setUsername(sp.getEmailAddress());
		// mailSender.setPassword(sp.getPassword());
		//		
		// String url = applicationHomePath(request);
		// url += RETRIEVE_PASSWORD_ACTION;
		// url += "?" + encryptedMessage(user, PARAM_ACCOUNT_NAME);
		// url += "&" + encryptedMessage(user, PARAM_MESSAGE);
		//		
		// String text = retrievePasswordMessage.getText();
		// retrievePasswordMessage.setText(StringUtils.replace(retrievePasswordMessage.getText(),
		// "%user%", user.getUserName()));
		// retrievePasswordMessage.setText(StringUtils.replace(retrievePasswordMessage.getText(),
		// "%uri%", url));
		// retrievePasswordMessage.setTo( user.getEmail());
		// mailSender.send(retrievePasswordMessage);
		// retrievePasswordMessage.setText(text);
		saveMessage("Amend the information has been sent to your e-mail, please check");
		return SUCCESS;
	}

	/**
	 * 参数信息
	 * 
	 * @param account
	 * @param param
	 * @return
	 */
	private String encryptedMessage(User user, String param) {
		StringBuffer sb = new StringBuffer();
		// user Email=MD5(userName)
		if (PARAM_ACCOUNT_NAME.equals(param)) {
			sb.append(PARAM_ACCOUNT_NAME + "=");
			sb.append(md5PasswordEncoder.encodePassword(user.getUserName(),
					null));
		}
		// user password=MD5(email+password)
		// else if (PARAM_MESSAGE.equals(param)) {
		// sb.append(PARAM_MESSAGE + "=");
		// String message = user.getEmail() + user.getPassword();
		// sb.append(md5PasswordEncoder.encodePassword(message, null));
		// }

		return sb.toString();
	}

	/**
	 * 重新设置密码
	 * 
	 * @return
	 */
	public String retrievePassword() {
		if (user == null)
			return INPUT;
		// if(user.get_email() == null || user.getOldPassword() == null){
		// addActionError("Url Err");
		// return INPUT;
		// }
		if (user.getUserName() == null || "".equals(user.getUserName().trim())) {
			addActionError("UserName is required");
			return INPUT;
		}
		if (user.getPassword() == null || "".equals(user.getPassword().trim())) {
			addActionError("Passowrd is required");
			return INPUT;
		}
		if (user.getConfirmPassword() == null
				|| "".equals(user.getConfirmPassword().trim())) {
			addActionError("ConfirmPassword is required");
			return INPUT;
		}
		if (!user.getPassword().equals(user.getConfirmPassword())) {
			addActionError("Password and ConfirmPassword do not meet");
		}
		// if(!user.get_email().equals(md5PasswordEncoder.encodePassword(user.getUserName(),
		// null))){
		// addActionError("Url Err");
		// return INPUT;
		// }
		List<User> list = userManager.findByNamedQuery("User.findByUserName",
				new Object[] { user.getUserName() });
		if (list == null || list.size() < 1) {
			addActionError("UserName Err");
			return INPUT;
		}
		User myUser = list.get(0);
		// if(!md5PasswordEncoder.encodePassword(myUser.getEmail()+myUser.getPassword(),
		// null).equals(user.getOldPassword())){
		// addActionError("Url Err");
		// return INPUT;
		// }
		myUser.setPassword(md5PasswordEncoder.encodePassword(
				user.getPassword(), null));
		userManager.updateEntity(myUser);
		saveMessage("Change your password success!");
		return SUCCESS;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List getRoleList() {
		List<Role> list = roleManager.findByCriteria(RoleAction
				.getCriteria(null));
		return list;
	}

	public void setRoleList(List roleList) {
		this.roleList = roleList;
	}

	public List getUserList() {
		return userList;
	}

	public void setUserList(List userList) {
		this.userList = userList;
	}

	public void setRoleManager(EntityManager roleManager) {
		this.roleManager = roleManager;
	}

	public List getSelectRoleList() {
		return selectRoleList;
	}

	public void setSelectRoleList(List selectRoleList) {
		this.selectRoleList = selectRoleList;
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}

	public void setMd5PasswordEncoder(Md5PasswordEncoder md5PasswordEncoder) {
		this.md5PasswordEncoder = md5PasswordEncoder;
	}

	public JavaMailSenderImpl getMailSender() {
		return mailSender;
	}

	public void setMailSender(JavaMailSenderImpl mailSender) {
		this.mailSender = mailSender;
	}

	public SimpleMailMessage getRetrievePasswordMessage() {
		return retrievePasswordMessage;
	}

	public void setRetrievePasswordMessage(
			SimpleMailMessage retrievePasswordMessage) {
		this.retrievePasswordMessage = retrievePasswordMessage;
	}

	public void setServeParameterManaegr(EntityManager serveParameterManaegr) {
		this.serveParameterManaegr = serveParameterManaegr;
	}

	/**
	 * @return the roleManager
	 */
	public EntityManager getRoleManager() {
		return roleManager;
	}

	/**
	 * @return the userManager
	 */
	public UserManager getUserManager() {
		return userManager;
	}

	/**
	 * @return the serveParameterManaegr
	 */
	public EntityManager getServeParameterManaegr() {
		return serveParameterManaegr;
	}

	/**
	 * @return the md5PasswordEncoder
	 */
	public Md5PasswordEncoder getMd5PasswordEncoder() {
		return md5PasswordEncoder;
	}

}
